package com.example.shop.common.util;

import com.example.shop.pojo.User;
import com.fasterxml.jackson.core.util.ByteArrayBuilder;
import io.netty.buffer.ByteBuf;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.Future;

public class FileOptionUtil {
    /**
     * 将指定的fileBytes数据，写入到指文件上
     * 如果指定的文件的目录不存在，则会自动创建其所有目录
     * 如果指定的文件也不存在，则会自动创建该文件
     * @param fileLocation 指定写入的文件路径名，文件名包含后缀名
     * @param fileBytes 数据
     * @throws IOException
     */
    public static void write(String fileLocation,byte[] fileBytes) throws IOException {
        //这里不能用file.isDirectory()，因为如果file不存在，则isDirectory()也是返回false
        if(!fileLocation.contains(".")){
            return;
        }
        int rightSlash = fileLocation.lastIndexOf("\\");
        int leftSlash = fileLocation.lastIndexOf("//");
        int singleLeftSlash = fileLocation.lastIndexOf("/");
        int max = Math.max(Math.max(rightSlash, leftSlash), singleLeftSlash);
        String directory = fileLocation.substring(0,max);
        File file = new File(directory);
        if(!file.exists()){
            file.mkdirs();
        }

        file = new File(fileLocation);
        if(!file.exists()){
            file.createNewFile();
        }
        FileOutputStream writer = new FileOutputStream(file);
        writer.write(fileBytes);
        writer.close();
    }

    /**
     * 无法读取超过4G的文件，如果读取超过4G文件的内容则会有损读取
     * @param fileLocation 指定读取的文件路径名，文件名包含后缀名
     * @return 如果指定的文件不存在，则返回null，否则读取该文件数据并返回
     * @throws IOException
     */
    public static byte[] read(String fileLocation) throws IOException {
        File file = new File(fileLocation);
        if(!file.exists() || file.isDirectory())
            return null;
        FileInputStream read = new FileInputStream(file);
        ByteBuffer byteBuffer = ByteBuffer.allocate(Math.toIntExact(file.length()));
        byte[] buffer = new byte[10240];
        int l;
        while((l = read.read(buffer))!=-1){
            byteBuffer.put(buffer,0,l);
        }
        return byteBuffer.array();
    }

    /**
     * 将指定的文件复制一份到指定的文件路径上
     * 如果要复制的文件不存在，则不会进行操作
     * 如果指定的文件路径不存在，则会自动创建
     * @param fileLocation 指定将存放复制文件的文件路径
     * @param copyFileLocation 指定要被复制的文件路径
     * @throws IOException
     */
    public static void copyFile(String fileLocation,String copyFileLocation) throws IOException {
//        FileOutputStream writer = new FileOutputStream(copyFileLocation);
//        File file = new File(fileLocation);
//        FileInputStream read = new FileInputStream(file);
//        byte[] buffer = new byte[10240];
//        int l;
//        while((l = read.read(buffer))!=-1){
//            writer.write(buffer,0,l);
//        }
//        writer.close();
//        read.close();
        byte[] data = read(copyFileLocation);
        if(data==null){
            return;
        }
        write(fileLocation,data);
    }

    /**
     * 异步复制文件
     * @param fileLocation 指定将存放复制文件的文件路径
     * @param copyFileLocation 指定要被复制的文件路径
     */
    public static Future<?> asyncCopyFile(String fileLocation,String copyFileLocation){
        Future<?> result = CachedThreadPoolUtil.submit(() -> {
            try {
                copyFile(fileLocation, copyFileLocation);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return result;
    }

    /**
     * 异步进行写入
     * @param fileLocation 指定写入的文件路径名，文件名包含后缀名
     * @param fileBytes 数据
     */
    public static Future<?> asyncWrite(String fileLocation,byte[] fileBytes) {
        Future<?> result = CachedThreadPoolUtil.submit(() -> {
            try {
                write(fileLocation, fileBytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return result;
    }

    /**
     * 删除指定目录下的所有文件
     * @param dirPath 要删除的目录
     * @param deleteSelf 是否要删除它本身。如果为true，最后也会将自己也删除掉
     */
    public static void deleteDir(String dirPath,boolean deleteSelf) throws IOException {
        File deleteDirectory = new File(dirPath);
        //如果删除的目录不存在，则不进行删除操作
        if(!deleteDirectory.exists()){
            return;
        }
        //获取到该目录下的所有文件名+文件后缀。即a.txt
        String[] fileList = deleteDirectory.list();
        for(String file:fileList){
            String filePath = dirPath+File.separator+file;
            File subFile = new File(filePath);
            if(subFile.isDirectory()){
                deleteDir(filePath,deleteSelf);
            }
            //删除文件或者文件夹时，会自动判断是否存在，如果不存在，则返回false，如果存在，则删除，返回true
            //删除文件夹时，如果文件夹不为空，则报错
            Files.deleteIfExists(Paths.get(filePath));
        }
        if(deleteSelf){
            Files.deleteIfExists(Paths.get(dirPath));
        }
    }

    /**
     * 删除指定目录下的所有文件
     * @param dirPath 要删除的目录
     * @param deleteSelf 是否要删除它本身。如果为true，最后也会将自己也删除掉
     */
    public static Future<?> asyncDeleteDir(String dirPath,boolean deleteSelf){
        Future<?> result = CachedThreadPoolUtil.submit(() -> {
            try {
                deleteDir(dirPath, deleteSelf);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return result;
    }
    public static boolean deleteFile(String deletePath) throws IOException {
        return Files.deleteIfExists(Paths.get(deletePath));
    }
    public static Future<?> asyncDeleteFile(String deletePath){
        Future<?> result = CachedThreadPoolUtil.submit(() -> {
            try {
                deleteFile(deletePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        return result;
    }
    public static boolean rename(String path,String renamePath){
        File file = new File(path);
        File renameFile = new File(renamePath);
        return file.renameTo(renameFile);
    }

    public static void main(String[] args) throws IOException {
//        FileOptionUtil.asyncCopyFile("D:\\no_one","D:\\no_one.jpg");
//        FileOptionUtil.asyncDeleteDir("D:\\electricity_shop\\resources\\merchant\\abc",true);
        FileOptionUtil.rename("D:\\1.jpg","D:\\2.jpg");
        FileOptionUtil.rename("D:\\electricity_shop\\a","D:\\electricity_shop\\b");
    }

}
